package com.ycj.config;

import com.ycj.HelloJob;
import lombok.extern.java.Log;
import org.quartz.*;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.*;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;

import java.lang.reflect.Method;
import java.util.concurrent.Executor;

@Configuration
@EnableAsync
@EnableScheduling
@EnableAspectJAutoProxy
@Log
public class Config {


    @Bean
    public Executor executor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("task-executor-");
        executor.initialize();
        return executor;
    }

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler();
        executor.setThreadNamePrefix("taskScheduler-");
        executor.initialize();
        return executor;
    }

    @Bean
    public AsyncConfigurer asyncConfigurer() {

        return new AsyncConfigurer() {
            @Override
            public Executor getAsyncExecutor() {
                return executor();
            }

            @Override
            public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
                return new AsyncUncaughtExceptionHandler() {
                    @Override
                    public void handleUncaughtException(Throwable ex, Method method, Object... params) {
                        log.info("handleUncaughtException---------------");
                    }
                };
            }
        };
    }

    @Bean
    public SchedulingConfigurer schedulingConfigurer() {

        return new SchedulingConfigurer() {
            @Override
            public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
                taskRegistrar.setTaskScheduler(taskScheduler());
            }


        };
    }

    //    @Bean("helloJob")
//    public JobDetail helloJobDetail() {
//        return JobBuilder.newJob(HelloJob.class)
//                .withIdentity("DateTimeJob")
//                .usingJobData("msg", "Hello Quartz")
//                .storeDurably()//即使没有Trigger关联时，也不需要删除该JobDetail
//                .build();
//    }
//
//    @Bean
//    public Trigger printTimeJobTrigger() {
//        // 每秒执行一次
//        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/1 * * * * ?");
//        return TriggerBuilder.newTrigger()
//                .forJob(helloJobDetail())
//                .withIdentity("quartzTaskService")
//                .withSchedule(cronScheduleBuilder)
//                .build();
//    }
    @Bean
    public JobDetailFactoryBean jobDetail() {
        JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean();
        jobDetailFactory.setJobClass(HelloJob.class);
        jobDetailFactory.setDescription("Invoke Sample Job service...");
        jobDetailFactory.setDurability(true);
        return jobDetailFactory;
    }

    @Bean
    public SimpleTriggerFactoryBean trigger(JobDetail job) {
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/1 * * * * ?");
        SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean();
        trigger.setJobDetail(job);
        trigger.setRepeatInterval(3600000);
        trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);

        return trigger;
    }

    @Bean
    public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetail job) {
        CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
        trigger.setCronExpression("0/1 * * * * ?");
        trigger.setJobDetail(job);
        return trigger;
    }

//    @Bean
//    public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetail jobDetail) {
//        SimpleTriggerFactoryBean simpleTriggerFactoryBean = new SimpleTriggerFactoryBean();
//        simpleTriggerFactoryBean.setJobDetail(jobDetail);
//        simpleTriggerFactoryBean.setRepeatCount(10);
//        simpleTriggerFactoryBean.setName("dsf");
//        return simpleTriggerFactoryBean;
//    }

//    @Bean
//    public SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean trigger) {
//        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
//        schedulerFactoryBean.setTriggers(trigger.getObject());
//        return schedulerFactoryBean;
//    }
}
